/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package atrevaluator;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;

/**
 *
 * @author iknoth
 */
public class ATREvaluator {

    private HashSet<String> reference;
    ArrayList<String> resultFiles;
    private Integer numberOfResults = Integer.MAX_VALUE;
    private boolean precision = true;
    private boolean recall = true;

    public boolean isPrecision() {
        return precision;
    }

    public boolean isRecall() {
        return recall;
    }

    public void setNumberOfResults(Integer numberOfResults) {
        this.numberOfResults = numberOfResults;
    }

    public ATREvaluator(String ATRResultsDir, ArrayList<String> referenceFiles) {

        ReadDirectory rd = new ReadDirectory(ATRResultsDir);
        rd.addExtension(".txt");
        this.resultFiles = rd.getRecursiveList();

        ReferenceDictionary refd = new ReferenceDictionary(referenceFiles);
        this.reference = refd.getReference();
    }

    public void evaluate() {

        ArrayList<Double> precisionList = new ArrayList<Double>();
        ArrayList<Double> recallList = new ArrayList<Double>();

        for (String filename : this.resultFiles) {

            precisionList.clear();
            recallList.clear();

            JatrResultParser jatrParser = new JatrResultParser(filename);
            jatrParser.parseFile();

            int all = 0;
            int correct = 0;
            int partlyCorrect = 0;

            System.out.println("Dictionary " + filename + " contains: " + jatrParser.getListResults().size() + " terms.");
            for (TermItem ti : jatrParser.getListResults()) {

                //boolean match = (this.reference.contains(ti.getStem()));
                boolean match =  false;
                Iterator<String> iter1 = this.reference.iterator();
                while (!match && iter1.hasNext()) {
                    match = (ti.equals(iter1.next()));
                }

                boolean partMatch = false;
                if (!match) {
                    Iterator<String> iter = this.reference.iterator();
                    while (!partMatch && iter.hasNext()) {
                        partMatch = (ti.fragmentEquals(iter.next()));
                    }
                }

                if (match) {
                    // 2 points for complete match
                    System.out.println("match " + ti.getStem());
                    correct++;                    
                //} else if (partMatch) {
                //    System.out.println("partMatch " + ti.getStem());
                //    partlyCorrect++;
                } else {
                    System.out.println("No match " + ti.getStem());
                }

                // beacause of precision calculation add 2
                all++;
                all++;

                precisionList.add(new Double(correct * 2 + partlyCorrect) / new Double(all));
                recallList.add(new Double(correct) / new Double(this.reference.size()));                
                if ((all % 1000) == 0) {
                    System.out.println("Computed: " + (all / 2));                    
                }
                
                if ((all / 2) >= this.numberOfResults) {
                    break;
                }
            } // end for each term           

            int lastDot = filename.lastIndexOf('.');
            if (this.precision) {
                String newPrecisionFilename = filename.substring(0, lastDot) + ".precision_dat";
                this.writeResults(newPrecisionFilename, precisionList);
            }
            
            if (this.recall) {
                String newRecallFilename = filename.substring(0, lastDot) + ".recall_dat";
                this.writeResults(newRecallFilename, recallList);
            }
            
        } //end for each file
    }

    public void writeResults(String filename, ArrayList<Double> precision) {
        InputOutput io = new InputOutput();
        io.writeToFile(filename, precision);
    }
}
